package control;

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import model.quadtree.Type;
import model.quadtree.graph.Node2Graph;
import model.quadtree.graph.QuadTree2Graph;

import view.MainWindow;

/**
 * The <code>UI</code> Controller. Get a instace of <code>MainWindow</code>,
 * implementing its event management.
 * 
 * @author 	Joao Carlos, Jody Matos
 * @version 1.1
 * @since	12/15/2011
 * 
 * <dt><b>History:</b></dt>
 * 	<dd>1.0: Create the <code>MainWindow</code> instance and set it visible.</dd>
 * 	<dd>1.1: Insert some <code>Mouse</code> and <code>MouseMotion</code> event handling.</dd> 
 */

public class MainWindowController implements ActionListener, MouseMotionListener, MouseListener{
	private MainWindow window;
	private Node2Graph root;
	private QuadTree2Graph tree;
	private List<Rectangle> obstacles;
	private Point startPoint;
	private Point endPoint;

	/**
	 * Create a instance of <code>MainWindowController</code>, making visible the UI,
	 * at <code>MainWindow</code>.
	 */
	public MainWindowController() {
		window = new MainWindow(this);
		window.setVisible(true);
		obstacles = new ArrayList<Rectangle>();
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource()==window.getObstaclesButton()){
			window.getObstaclesButton().setEnabled(false);
			window.getPointsButton().setEnabled(true);
			window.setMessageLabel("Insert start and end Points");
		} else if(e.getSource()==window.getPointsButton()){
			window.getPointsButton().setEnabled(false);
			window.getQuadtreeButton().setEnabled(true);
			window.setMessageLabel("When ready, make quadtree!");
		} else if(e.getSource()==window.getQuadtreeButton()){
			window.getQuadtreeButton().setEnabled(false);
			window.getRouteButton().setEnabled(true);
			window.setMessageLabel("When ready, make route!");

			root = new Node2Graph(Type.WHITE, new Point(window.getFieldPanel().getWidth(), 0), 
					new Point(0, window.getFieldPanel().getHeight()));
			tree = new QuadTree2Graph(root);
			tree.makeChildren(root);
			tree.verifyGreys(obstacles);
			tree.verifyNeighborhood();
			window.paintQuadtreeCells(tree.getLeafNodes());
			
			if(tree.debug()){	
				@SuppressWarnings("rawtypes")
				Enumeration keys = tree.getLeafNodes().keys();
				while(keys.hasMoreElements()){
					System.out.println(keys.nextElement());
				}
				/*for(Edge edge : tree.getEdges()){
					System.out.println(edge.getA().getId()+" is neighbor of "+edge.getB().getId());
					System.out.println("  Distance: "+edge.getDelta());
				}*/
				double[][] edges = tree.getEdges();
		        // Writing the result tree in a binary file
				try {
					ObjectOutputStream outs = new ObjectOutputStream(new FileOutputStream(Config.workDir + "graph.bin"));
		        	outs.writeObject(edges);
			        outs.close();				
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				for(int i=0;i<tree.getEdges().length;i++){
					for(int j=0;j<tree.getEdges().length;j++){
						if(edges[i][j]!=Double.MAX_VALUE){
							System.out.println(i+" is neighbor of "+j);
							System.out.println("  Distance: "+edges[i][j]);
						}
					}
				}
			}
		} else if(e.getSource()==window.getRouteButton()){
			window.getRouteButton().setEnabled(false);
			window.getSendButton().setEnabled(true);
			window.setMessageLabel(" When ready, send to robot");
		}  else if(e.getSource()==window.getSendButton()){
			window.getSendButton().setEnabled(false);
			window.getStartButton().setEnabled(true);
			window.setMessageLabel("When ready, start the moving!");
		}else if(e.getSource()==window.getStartButton()){
			window.getStartButton().setEnabled(false);
			window.setMessageLabel("  watch the robot moving!");
		}
	}

	@Override
	public void mouseDragged(MouseEvent e) {
		if(window.getObstaclesButton().isEnabled())
			window.mousePressed(e.getX(), e.getY());
	}

	@Override
	public void mouseMoved(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mouseClicked(MouseEvent e) {
		if(window.getPointsButton().isEnabled()){
			if(startPoint==null){
				startPoint = new Point(e.getX(), e.getY());
				window.paintStartPoint(startPoint);
				Rectangle rect = new Rectangle(e.getX(), e.getY(), 20, 20);
				obstacles.add(rect);
			}
			else if (endPoint==null){
				endPoint = new Point(e.getX(), e.getY());
				window.paintEndPoint(endPoint);
				Rectangle rect = new Rectangle(e.getX(), e.getY(), 20, 20);
				obstacles.add(rect);
			}
		}
	}

	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mouseReleased(MouseEvent e) {
		System.out.println("Soltou!");
		Rectangle rect = new Rectangle(window.getRectX(), window.getRectY(),
				window.getRectWidth(), window.getRectHeight());
		obstacles.add(rect);
		window.paintRects(rect);
		window.setClicked(false);
		System.out.println("fieldWidth:"+window.getFieldPanel().getWidth());
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub

	}
}
